package edzest.service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import edzest.interfaces.SungJukService;
import edzest.model.SungJukVO;

public class JDBCSungJuk implements SungJukService{
	
	// JDBC 접속 정보
	private static final String DRV = 
			"oracle.jdbc.OracleDriver";
	private static final String URL = 
			"jdbc:oracle:thin:@//localhost:1521/xe";
	private static final String USR = "scott";
	private static final String PWD = "TIGER";
		
	// SQL 문 작성
	private static final String insertSQL = 
			"insert into SUNGJUK(sjno, name, kor, eng, mat) VALUES(SJNO.nextval,?,?,?,?)";
	private static final String selectSQL = 
			"select * from sungjuk order by sjno desc";
	private static final String updateSQL = 
			"update sungjuk set name = ?,kor = ?,"
			+ " eng = ?, mat = ? where sjno = ?"; // 물음표 5개
	private static final String deleteSQL = 
			"delete from sungjuk where sjno = ?";
			// Statement대신 PreparedStatement쓰는 이유
			// PreparedStatement는 SQL문을 캐시에 남겨둬서 
			// 컴파일할 때마다 SQL문을 기계어로 바꾸지않고 바로 사용
			// "delete from sungjuk where sjno = ?"에서 ?만 바뀌므로
			// delete from sungjuk where sjno = 는 캐시에 기계어로 만들어놈
	
	@Override
	public boolean newSungJuk(SungJukVO sj) {
		Connection conn = null;
		PreparedStatement ps = null;
		boolean result = false;
		
		try{ // try붙은 이유: 코드만든 사람이 강제적으로 우리가 코드사용할 때 예외처리하게 throw함
			Class.forName( DRV );
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(insertSQL);
			  // ? 매개변수에 들어갈 실제 입력값을 지정
				ps.setString(1, sj.getName()); // 첫번째 매개변수 의미: ?(물음표)입력된 순서. 순서대로 번호 지정
				// ps.setInt(2, sj.getName()); -> 두번째 매개변수에 스트링값 와서 에러
				// The method setInt(int, int) in the type PreparedStatement 
				// is not applicable for the arguments (int, String)
				ps.setInt(2, sj.getKor());
				ps.setInt(3, sj.getEng());
				ps.setInt(4, sj.getMat());
				
			int cnt = ps.executeUpdate();
			// 성공적으로 insert 되면 result를 true로
			if (cnt > 0) result = true;
		} catch (Exception ex){
			ex.printStackTrace();
		} finally {
			if(ps != null) 
				try { ps.close(); }catch(Exception e){}
			if(conn != null)
				try { conn.close(); }catch(Exception e){}
		}
		
		return result;
	}

	@Override
	public String readSungJuk() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		String result = "";
		
		try { // try붙은 이유: 코드만든 사람이 강제적으로 우리가 코드사용할 때 예외처리하게 throw함
			  // JDBC 드라이버가 없으면 ClassNotFoundException이 발생하므로반드시 try-catch 문을사용
			Class.forName( DRV );
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(selectSQL);
			rs = ps.executeQuery();
			// select문의 결과가 rs에 담김
			
			// selectSQL 실행결과를 모두 출력
			while(rs.next()) {
				for(int i=1; i<=9; ++i)
					result += rs.getString(i) + " ";
					// 자동적으로 형변환이 됨
				result += "\n";
			}
		} catch(Exception ex) {
			ex.printStackTrace();
		} finally { // 생성 역순으로 작성
			if(rs != null) 
				try{rs.close();}catch(Exception e){}
			if(ps != null) 
				try{ps.close();}catch(Exception e){}
			if(conn != null) 
				try{conn.close();}catch(Exception e){}
		}
		
		return result;  // 행을 리턴
	}

	@Override
	public boolean modifySungJuk(SungJukVO sj) {
		Connection conn = null;
		PreparedStatement ps = null;
		boolean result = false;
		// return result; 리턴 밑의 코드는 다 에러처리됨. 리턴은 제일 아래에 작성
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement(updateSQL);
				ps.setString(1, sj.getName());
			 // ps.setString(1, sj.getKor());
			 // The method setString(int, String) 
			 // in the type PreparedStatement is not 
		   	 // applicable for the arguments (int, int)
				ps.setInt(2, sj.getKor());
				ps.setInt(3, sj.getEng());
				ps.setInt(4, sj.getMat());
				ps.setString(5, sj.getSjno());
			int cnt = ps.executeUpdate();
			if(cnt > 0) result = true;
		} catch(Exception ex){
			ex.printStackTrace();
		} finally{
			if(ps != null) 
				try{ps.close();}catch(Exception e){}
			if(conn != null) 
				try{conn.close();}catch(Exception e){}
		}
		
		return result;
	}

	@Override
	public boolean removeSungjuk(String key) {
		Connection conn = null;
		PreparedStatement ps = null;
		boolean result = false; // 삭제가 잘되었는지 안되었는지 확인하는 불리언
		
		try{
			Class.forName( DRV ); 
			conn = DriverManager.getConnection(URL, USR, PWD);
			ps = conn.prepareStatement( deleteSQL );
				ps.setString(1, key);
				// 첫번째 ?자리에 들어갈 값 지정
			int cnt = ps.executeUpdate();
				// sql문 실행 후 결과 반환
			if(cnt > 0) result = true;
				
		} catch(Exception ex){
			ex.printStackTrace();
		} finally {
			if (ps != null) 
				try{ps.close();}catch(Exception e){}
			if (conn != null) 
				try{conn.close();}catch(Exception e){}
		}
		return result;
	}

}
